///////////////////////////////////////////////////////////////////////////////
// File:        BigNumber.hpp
// Author:      671643387@qq.com
// Description:
///////////////////////////////////////////////////////////////////////////////

#ifndef SHARED_AUTH_BIGNUMBER_HPP_
#define SHARED_AUTH_BIGNUMBER_HPP_

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif

#include <cstdint>

///////////////////////////////////////////////////////////////////////////////
struct bignum_st;

///////////////////////////////////////////////////////////////////////////////

class BigNumber
{
public:
    ///////////////////////////////////////////////////////////////////////////
    BigNumber(void);
    BigNumber(const BigNumber& bn);
    BigNumber(uint32_t);
    ~BigNumber(void);

public:
    ///////////////////////////////////////////////////////////////////////////
    void SetUInt32(uint32_t);
    void SetUInt64(uint64_t);
    void SetBinary(const uint8_t*, int);
    void SetHexStr(const char*);
    void SetRand(int);

    static void Free(void*);

    ///////////////////////////////////////////////////////////////////////////
    BigNumber operator=(const BigNumber&);

    BigNumber operator+=(const BigNumber&);
    BigNumber operator+(const BigNumber& x)
    {
        BigNumber t(*this);
        return t += x;
    }

    BigNumber operator-=(const BigNumber&);
    BigNumber operator-(const BigNumber& x)
    {
        BigNumber t(*this);
        return t -= x;
    }

    BigNumber operator*=(const BigNumber&);
    BigNumber operator*(const BigNumber& x)
    {
        BigNumber t(*this);
        return t *= x;
    }

    BigNumber operator/=(const BigNumber&);
    BigNumber operator/(const BigNumber& x)
    {
        BigNumber t(*this);
        return t /= x;
    }

    BigNumber operator%=(const BigNumber&);
    BigNumber operator%(const BigNumber& x)
    {
        BigNumber t(*this);
        return t %= x;
    }

    ///////////////////////////////////////////////////////////////////////////
    bool IsZero(void) const;
    BigNumber ModExp(const BigNumber&, const BigNumber&);
    BigNumber Exp(const BigNumber&);
    int GetNumBytes(void);
    struct bignum_st* BN(void) { return bn_; }
    uint32_t AsUInt32(void);
    uint8_t* AsByteArray(int minSize = 0);
    const char* AsHexStr(void);
    const char* AsDecStr(void);

private:
    ///////////////////////////////////////////////////////////////////////////
    struct bignum_st*   bn_;
    uint8_t*            array_;
};

#endif /* SHARED_AUTH_BIGNUMBER_HPP_ */
